Skip to content

AIR CLI: drop max_retries from the ai_runtime_task payload#5813

Merged
riddhibhagwat-db merged 1 commit into
air-clifrom
air-max-retries-fix
Jul 8, 2026
Merged

AIR CLI: drop max_retries from the ai_runtime_task payload#5813
riddhibhagwat-db merged 1 commit into
air-clifrom
air-max-retries-fix

Conversation

@riddhibhagwat-db

@riddhibhagwat-db riddhibhagwat-db commented Jul 2, 2026

Copy link
Copy Markdown

Changes

Send max_retries on the ai_runtime_task submit payload whenever it is set, so the user's YAML value is honored end-to-end:

  • max_retries unset defaults to 3 and is sent (matches the Python CLI default, sdk/config.py Field(default=3)).
  • max_retries: N (N > 0) gets sent, with retry_on_timeout: true.
  • max_retries: 0 ussent explicitly ("max_retries":0); retry_on_timeout is omitted.

max_retries is always marshaled (no omitempty) so an explicit 0 reaches the server. retry_on_timeout keeps omitempty and is set only when max_retries > 0, so the wire form matches the Python CLI (which never emits a bare retry_on_timeout: false). The YAML field and its >= 0 validation are unchanged.

Why

On the ai_runtime_task path, retries are honored via the Jobs task max_retries field: Jobs performs the retry, and each attempt is created as its own AIR workload.

The bug was that max_retries was previously sent unconditionally including 0, but 0 was being dropped/ignored so that setting max_retries: 0 to disable retries silently fell back to the server default and the workload still retried. Sending 0 explicitly makes "no retries" actually take effect.

This intentionally diverges from the Python CLI's native branch by one case: Python only adds the field under if max_retries > 0, so Python's max_retries: 0 silently reverts to the server default. We send 0 so the user's intent is honored.

Tests

  • TestBuildSubmitPayload: max_retries: 2 means task has MaxRetries == 2, RetryOnTimeout == true.
  • TestBuildSubmitPayloadDefaultRetries: unset var means MaxRetries == 3 (defaultMaxRetries), RetryOnTimeout == true
  • TestBuildSubmitPayloadNoRetries: max_retries: 0 should result in marshaled JSON contains "max_retries":0 and no retry_on_timeout.
  • go test ./experimental/air/... and ./task lint-q pass
  • manual verification passes

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

Could not determine reviewers from git history.
Round-robin suggestion: @apeforest

Eligible reviewers: @apeforest, @ben-hansen-db, @bfontain, @lu-wang-dl, @maggiewang-db, @panchalhp-db, @pardis-beikzadeh-db, @vinchenzo-db

Suggestions based on git history. See OWNERS for ownership rules.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: f17e688

Run: 28873870844

Env 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 267 1026 6:59
💚​ aws windows 4 4 269 1024 9:42
💚​ aws-ucws linux 4 4 363 940 10:47
💚​ aws-ucws windows 4 4 365 938 12:28
💚​ azure linux 4 4 264 1026 7:43
💚​ azure windows 4 4 266 1024 9:26
🔄​ azure-ucws linux 3 3 4 360 938 12:15
💚​ azure-ucws windows 4 4 364 936 11:56
💚​ gcp linux 4 4 260 1029 7:15
💚​ gcp windows 4 4 262 1027 10:57
10 interesting tests: 4 SKIP, 3 flaky, 3 RECOVERED
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🔄​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/bundle/resources/apps/inline_config ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 29 slowest tests (at least 2 minutes):
duration env testname
5:01 azure-ucws windows TestAccept
4:58 aws-ucws windows TestAccept
4:57 azure windows TestAccept
4:56 aws windows TestAccept
4:55 gcp windows TestAccept
4:31 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:29 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:24 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:16 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:52 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:48 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:39 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:37 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:21 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:09 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:58 azure linux TestAccept
2:56 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:53 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:51 aws linux TestAccept
2:50 gcp linux TestAccept
2:49 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:48 aws-ucws linux TestAccept
2:48 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:48 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:43 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:42 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:41 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:38 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:33 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

@maggiewang-db maggiewang-db left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execution retries are driven by the AI Runtime service (AICM) - Is it true?

@ben-hansen-db How is a user supposed to specify the max retry number with the new BYOT?

The ai_runtime_task path DOES honor the Jobs task max_retries field —
Jobs performs the retry and each attempt is created as a fresh AI Runtime
(AICM) workload (see ai-training AiTrainingHandlers: "Each Jobs retry
attempt is created as its own AICM workload"). So the retry knob is real.

Send max_retries whenever it is set (including 0), so the user's YAML
value is honored end-to-end:

- max_retries unset -> defaults to 3 (matches Python: sdk/config.py
  Field(default=3)).
- max_retries: N>0 -> sent, retry_on_timeout: true.
- max_retries: 0 -> sent explicitly ("max_retries":0), retry_on_timeout
  omitted. This diverges from the Python CLI (which drops the field
  under `if max_retries > 0`) so that 0 actually means "no retries"
  instead of silently falling back to the server default.

Co-authored-by: Isaac
@riddhibhagwat-db riddhibhagwat-db merged commit b3b7ec8 into air-cli Jul 8, 2026
21 checks passed
@riddhibhagwat-db riddhibhagwat-db deleted the air-max-retries-fix branch July 8, 2026 04:47

@vinchenzo-db vinchenzo-db left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pr desc may be out of date. Also @maggiewang-db I believe Jobs drives the retry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants